This chunk mapped the engine displacement verse and highway mpg. Plotted these values on a graph.
Enter your code chunks for Section 3.2 here.
Get in the habit of entering a brief description of what each chunk of code does. Enter this above the chunk, like I did in Section 3.1.
Section 3.2 Questions
Answer the questions completely. Some answers will require you to write code in a code chunk and also to type text before or after the chunk. Other answers will require only code or only text.
1: Run ggplot(data = mpg). What do you see? An empty graph box
ggplot(data = mpg)
Warning messages:
1: In readChar(file, size, TRUE) : truncating string with embedded nuls
2: In readChar(file, size, TRUE) : truncating string with embedded nuls
3: In readChar(file, size, TRUE) : truncating string with embedded nuls
4: In readChar(file, size, TRUE) : truncating string with embedded nuls

2: How many rows are in mpg? How many columns? Hint: Use the dim() function. Type dim() in the console to learn what dim() does.
dim(mpg)
[1] 234 11
3: What does the drv variable describe? drv variable describes the type of drive train, where f = front-wheel drive, r = rear wheel drive, 4 = 4wd Read the help for ?mpg to find out.
?mpg
4: Make a scatterplot of hwy vs cyl.
ggplot(data = mpg)+
geom_point(mapping = aes(x=cyl, y=hwy))

5: What happens if you make a scatterplot of class vs drv? Why is the plot not useful? The plot is not useful because the classes of cars can have multiple plots mapped for the type of drive trains available.
ggplot(data = mpg)+
geom_point(mapping = aes(x=class, y=drv))

Section 3.3: Aesthetic mappings
Scatterplot with car class coded
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, color = class))

Scatterplot coded by car size
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, size = class))

Scatterplot with alpha aesthetic
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, alpha = class))

Scatterplot with shape aesthetic
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, shape = class))

Scatterplot with manual color added
ggplot(data = mpg) +
There were 19 warnings (use warnings() to see them)
geom_point(mapping = aes(x = displ, y = hwy), color = "blue")

Section 3.3 questions
1: What’s gone wrong with this code? Why are the points not blue? In order to manually set a plot color, the color has to be located outside of the geom function aes()
2: Which variables in mpg are categorical? Variables that are categorical do not contain an integer or hold a numerical value. So, manufacturer, model, transmission, drive train, fuel type, and class are all categorical variables. Which variables are continuous? The variables that hold a numerical value or is an integer would be a continuous variable. So, displacement, year, cylinder, city mpg, and hwy mpg would be the continuous variables. (Hint: type ?mpg to read the documentation for the dataset). How can you see this information when you run mpg? When running ?mpg it did not return any help or results. An online search suggested running help(mpg) instead. The help results displayed the types of variables listed for the data and described their content.
?mpg
help(mpg)
3: Map a continuous variable to color, size, and shape. How do these aesthetics behave differently for categorical vs. continuous variables? Aesthetics behave best for categorical variables. Note: You need several code chunks here to answer this question.
ggplot(data = mpg)+
geom_point(mapping = aes(x=displ, y=hwy, color=cty))

ggplot(data = mpg)+
geom_point(mapping = aes(x=displ, y=hwy, size=cty))

ggplot(data = mpg)+
geom_point(mapping = aes(x=displ, y=hwy, alpha=cty))

ggplot(data = mpg)+
geom_point(mapping = aes(x=displ, y=hwy, shape=cty))
Error: A continuous variable can not be mapped to shape

4: What happens if you map the same variable to multiple aesthetics? In this case, varying classes were distinguished by both different shapes and colors.
ggplot(data = mpg)+
geom_point(mapping = aes(x=displ, y=hwy, shape=class, color=class))

5: What does the stroke aesthetic do? Use the stroke aesthetic to modify the width of the border. What shapes does it work with? Only shapes that have a border. (Hint: use ?geom_point)
?geom_point
ggplot(mtcars, aes(wt, mpg)) +
geom_point(shape = 21, colour = "black", fill = "white", size = 5, stroke = 5)

6: What happens if you map an aesthetic to something other than a variable name, like aes(colour = displ < 5)? It displays points in color based on whether they meet the named parameter or not.
ggplot(data = mpg)+
geom_point(mapping = aes(x=displ, y=hwy, color= displ <5))

Section 3.5: Facets
Split plot into facets
ggplot(data = mpg) +
There were 40 warnings (use warnings() to see them)
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_wrap(~ class, nrow = 2)

Split plot into variables
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_grid(drv ~ cyl)

Section 3.5 questions
1: What happens if you facet on a continuous variable? Note: Write a prediction, then make and run your code chunk. Prediction: Adding a facet to a continuous variable will not split the variable into all subplots.
ggplot(data = mpg)+
geom_point(mapping = aes(x=displ, y=hwy))+
facet_wrap(~year)

2: What do the empty cells in plot with facet_grid(drv ~ cyl) mean? How do they relate to this plot? For this data, empty subplots represent the drive train and cylinder pairing was either not tested or not an availbe vehicle option
ggplot(data = mpg)+
geom_point(mapping = aes(x=displ, y=hwy))+
facet_grid(drv ~ cyl)

3: What plots does the following code make? What does . do? It chooses the dimension of the subplots. The ‘.’ displays the data in rows whereas the other one is displayed in columns..
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_grid(drv ~ .)

ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_grid(. ~ cyl)

4: Take the first faceted plot below. What are the advantages to using faceting instead of the colour aesthetic? It allows for additional variables to be used to split the data. What are the disadvantages? Can only be used on categorical data. How might the balance change if you had a larger dataset? Too many subplots to easily compare the data.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_wrap(~ class, nrow = 2)

5: Read ?facet_wrap. What does nrow do? ‘nrow’ controls the number of rows. What does ncol do? ‘ncol’ controls the number of number columns. What other options control the layout of the individual panels? Direction ‘dir’ because they could be in either a vertical or horizontal layout. Why doesn’t facet_grid() have nrow and ncol argument?j In facet_grid the number of variable predetermines the number of rows and columns.
?facet_wrap
6: When using facet_grid() you should usually put the variable with more unique levels in the columns. Why? So the axis is more spread out allowing all the data to be seen.
?facet_grid
Section 3.6: Geometric objects
Scatterplot of mpg data
ggplot(data = mpg) +
There were 22 warnings (use warnings() to see them)
geom_point(mapping = aes(x = displ, y = hwy))

Line graph of mpg data
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy))

Linegraph divided in 3 aesthetic line types
ggplot(data = mpg) +
There were 24 warnings (use warnings() to see them)
geom_smooth(mapping = aes(x = displ, y = hwy, linetype = drv))

Line Graph
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy))

Line graph with line types showing vehicle drive train types
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy, group = drv))

Line graph with drive train type indicated with multiple colored lines
ggplot(data = mpg) +
geom_smooth(
mapping = aes(x = displ, y = hwy, color = drv),
show.legend = FALSE
)

Scatterplot and line graph of mpg data
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
geom_smooth(mapping = aes(x = displ, y = hwy))

Line graph and scatterplot with color aesthetic
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = class)) +
geom_smooth()

Line graph and scatterplot with color aesthetic without standard deviation
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = class)) +
geom_smooth(data = filter(mpg, class == "subcompact"), se = FALSE)

Section 3.6.1 Questions
1: What geom would you use to draw a line chart? ‘geom_line’ A boxplot? ‘geom_boxplot’ A histogram? ‘geom_histogram’ An area chart? ‘geom_area’ Note: You will have to make some types of these charts in Part 2 of this assignment.
?geom_area
2: Run this code in your head and predict what the output will look like. Prediction: Scatter plots and a single line of data. Then, run the code in R and check your predictions.
ggplot(data = mpg, mapping = aes(x = displ, y = hwy, color = drv)) +
geom_point() +
geom_smooth(se = FALSE)

3: What does show.legend = FALSE do? It removes the legend. What happens if you remove it? Then the legend appears. Note: Skip the “Why do you think I used it earlier in the chapter?” question.
4: What does the se argument to geom_smooth() do? It adds upper and lower error limits or confidence bands.
5: Will these two graphs look different? Why/why not? No. They display the same data the code is just written in two different ways.
6: Recreate the R code necessary to generate the following graphs. Note: Enter a separate code chunk for each graph, numbered 1 to 6, starting row-wise at upper left.
1: upper left.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy), size=5) +
geom_smooth(mapping = aes(x = displ, y = hwy), se= FALSE)

2: upper right.
ggplot(data = mpg) +
geom_point (mapping = aes(x =displ, y = hwy), size=5)+
geom_smooth(mapping = aes(x = displ, y = hwy, group = drv), se= FALSE)

3: middle left.
ggplot(data = mpg, mapping = aes(x = displ, y = hwy, color = drv, size= 4)) +
geom_point() +
geom_smooth(se = FALSE)

4: middle right.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, color= drv), size=5) +
geom_smooth(mapping = aes(x = displ, y = hwy), se= FALSE)

5: lower left.
ggplot(data = mpg, mapping = aes(x = displ, y = hwy, color = drv, size= 3)) +
geom_point() +
geom_smooth(aes(linetype= drv), se = FALSE)

6: lower right. Hint: Read the help file for geom_point. Use shape = 21, stroke = 2, and size = 3.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, color= drv), shape= 21, size=3, stroke=2)

Section 3.8 Position adjustments
Bar graph
ggplot(data = diamonds) +
There were 38 warnings (use warnings() to see them)
geom_bar(mapping = aes(x = cut, colour = cut))

Colored Bar Graph
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = cut))

Bar graph with position adjustment
ggplot(data = diamonds) +
There were 50 or more warnings (use warnings() to see the first 50)
geom_bar(mapping = aes(x = cut, fill = clarity))

Bar graph with low alpha position adjustment
ggplot(data = diamonds, mapping = aes(x = cut, fill = clarity)) +
geom_bar(alpha = 1/5, position = "identity")

Bar graph without fill
ggplot(data = diamonds, mapping = aes(x = cut, colour = clarity)) +
geom_bar(fill = NA, position = "identity")

Bar graph with fill
ggplot(data = diamonds) +
There were 50 or more warnings (use warnings() to see the first 50)
geom_bar(mapping = aes(x = cut, fill = clarity), position = "fill")

Bar graph with dodge position
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = clarity), position = "dodge")

Scatterplot with jitter
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy), position = "jitter")

Section 3.8 Questions
1: What is the problem with this plot? Some points are not displayed due to over plotting. How could you improve it. It can be improved by setting the position adjustment to jitter. Hint: Remember the size of the mpg data set from earlier in this exercise. Does the number of points seem correct? Note: Write the code to improve it.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy), position = "jitter")
2: What parameters to geom_jitter() control the amount of jittering? Width and Height
3: Compare and contracts geom_jitter() with geom_count(). Both features provide position adjustment. Count determines the number of overlapping points. Jitter adds noise to the overlaps so more of hte plots are seen.
4: What is the default position adjustement for geom_boxplot()? The default position is dodge2. Create a visualization of the mpg dataset that demonstrates it.
ggplot(mpg, aes(displ, hwy)) +
geom_boxplot(aes(group = cty))
Section 3.9: Coordinate systems
Note: Read about and do only the code chunk associated with coord_flip(). coord_flip() is a great layer to use when you have categorical data with longish names as it makes the text easier to read.
Boxplot
ggplot(data = mpg, mapping = aes(x = class, y = hwy)) +
geom_boxplot()

Boxplot with coordinates flipped
ggplot(data = mpg, mapping = aes(x = class, y = hwy)) +
geom_boxplot() +
coord_flip()

Section 3.10: The layered grammar of graphics
Just read this section as a contextual review of everything you just learned.
LS0tCnRpdGxlOiAiSFcwNCBQYXJ0IDE6IENvbXBsZXRlIENoYXB0ZXIgMyIKYXV0aG9yOiAiQWxpc3NhIFNlYWwiCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVkICVCICVZJylgIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBpbmxpbmUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCiMjIENoYXB0ZXIgMwoKLSBDaGFuZ2UgInlvdXIgbmFtZSIgaW4gdGhlIFlBTUwgaGVhZGVyIGFib3ZlIHRvIHlvdXIgbmFtZS4KCiMjIyBTZWN0aW9uIDMuMQoKTG9hZCB0aGUgdGlkeXZlcnNlIHBhY2thZ2VzLiBJJ3ZlIGVudGVyZWQgdGhlIGZpcnN0IGNvZGUgY2h1bmsgZm9yIHlvdS4gKipZb3UgbXVzdCBlbnRlciBhbGwgc3Vic2VxdWVudCBjb2RlIGNodW5rcyBhbmQgcnVuIHRoZSBjb2RlLioqIAoKYGBge3J9CmxpYnJhcnkoInRpZHl2ZXJzZSIpCmBgYAoKSWYgeW91IGdldCBhbiBlcnJvciwgdGhlbiB5b3UgZGlkIG5vdCBpbnN0YWxsIHRoZSBgdGlkeXZlcnNlYCBwYWNrYWdlIGxpa2UgeW91IHdlcmUgc3VwcG9zZWQgdG8gaW4gdGhlIHByZXZpb3VzIGFzc2lnbm1lbnQuIEdvIGJhY2sgdG8gdGhhdCBhc3NpZ25tZW50IGFuZCBjb21wbGV0ZSB0aGF0IHN0ZXAuIChUaGlzIHNob3VsZCBub3QgYmUgdGhlIGNhc2UsIHRob3VnaC4pCgojIyMgU2VjdGlvbiAzLjI6IEZpcnN0IHN0ZXBzCgpMb2FkIG1wZyBkYXRhIAoKYGBge3J9CmdncGxvdDI6Om1wZwpgYGAKCiMjIFRoaXMgY2h1bmsgZGlzcGxheWVkIGluZm9ybWF0aW9uIGFib3V0IGEgdmVoaWNsZSBtYW51ZmFjdHVyZXIsIG1vZGVsLCBlbmdpbmUgZGlzcGxhY2VtZW50LCB5ZWFyLCBudW1iZXIgb2YgY3lsaW5kZXJzLCB0eXBlIG9mIHRyYW5zbWlzc2lvbiwgZHJpdmUgdHJhaW4sIGNpdHkgbXBnLCBoaWdod2F5IG1wZywgZnVlbCB0eXBlLCBhbmQgY2xhc3Mgb2YgY2FyLgoKQ3JlYXRlIGEgc2NhdHRlcnBsb3QKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IG1wZykgKyAKICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkKYGBgCgojIyBUaGlzIGNodW5rIG1hcHBlZCB0aGUgZW5naW5lIGRpc3BsYWNlbWVudCB2ZXJzZSBhbmQgaGlnaHdheSBtcGcuIFBsb3R0ZWQgdGhlc2UgdmFsdWVzIG9uIGEgZ3JhcGguIAoKRW50ZXIgeW91ciBjb2RlIGNodW5rcyBmb3IgU2VjdGlvbiAzLjIgaGVyZS4KCkdldCBpbiB0aGUgaGFiaXQgb2YgZW50ZXJpbmcgYSBicmllZiBkZXNjcmlwdGlvbiBvZiB3aGF0IGVhY2ggY2h1bmsgb2YgY29kZSBkb2VzLiBFbnRlciB0aGlzIGFib3ZlIHRoZSBjaHVuaywgbGlrZSBJIGRpZCBpbiBTZWN0aW9uIDMuMS4KCiMjIyMgU2VjdGlvbiAzLjIgUXVlc3Rpb25zCgpBbnN3ZXIgdGhlIHF1ZXN0aW9ucyAqY29tcGxldGVseS4qIFNvbWUgYW5zd2VycyB3aWxsIHJlcXVpcmUgeW91IHRvIHdyaXRlIGNvZGUgaW4gYSBjb2RlIGNodW5rIGFuZCBhbHNvIHRvIHR5cGUgdGV4dCBiZWZvcmUgb3IgYWZ0ZXIgdGhlIGNodW5rLiBPdGhlciBhbnN3ZXJzIHdpbGwgcmVxdWlyZSBvbmx5IGNvZGUgb3Igb25seSB0ZXh0LiAKCioqMToqKiBSdW4gZ2dwbG90KGRhdGEgPSBtcGcpLiBXaGF0IGRvIHlvdSBzZWU/IEFuIGVtcHR5IGdyYXBoIGJveAoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKQpgYGAKCioqMjoqKiBIb3cgbWFueSByb3dzIGFyZSBpbiBgbXBnYD8gSG93IG1hbnkgY29sdW1ucz8gKipIaW50OioqIFVzZSB0aGUgYGRpbSgpYCBmdW5jdGlvbi4gVHlwZSBgZGltKClgIGluIHRoZSBjb25zb2xlIHRvIGxlYXJuIHdoYXQgYGRpbSgpYCBkb2VzLgpgYGB7cn0KZGltKG1wZykKYGBgCgoKKiozOioqIFdoYXQgZG9lcyB0aGUgYGRydmAgdmFyaWFibGUgZGVzY3JpYmU/IGRydiB2YXJpYWJsZSBkZXNjcmliZXMgdGhlIHR5cGUgb2YgZHJpdmUgdHJhaW4sIHdoZXJlIGYgPSBmcm9udC13aGVlbCBkcml2ZSwgciA9IHJlYXIgd2hlZWwgZHJpdmUsIDQgPSA0d2QgIFJlYWQgdGhlIGhlbHAgZm9yIGA/bXBnYCB0byBmaW5kIG91dC4gCgpgYGB7cn0KP21wZwpgYGAKCioqNDoqKiBNYWtlIGEgc2NhdHRlcnBsb3Qgb2YgYGh3eWAgdnMgYGN5bGAuCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpKwogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4PWN5bCwgeT1od3kpKQpgYGAKCgoqKjU6KiogV2hhdCBoYXBwZW5zIGlmIHlvdSBtYWtlIGEgc2NhdHRlcnBsb3Qgb2YgYGNsYXNzYCB2cyBgZHJ2YD8gV2h5IGlzIHRoZSBwbG90IG5vdCB1c2VmdWw/IFRoZSBwbG90IGlzIG5vdCB1c2VmdWwgYmVjYXVzZSB0aGUgY2xhc3NlcyBvZiBjYXJzIGNhbiBoYXZlIG11bHRpcGxlIHBsb3RzIG1hcHBlZCBmb3IgdGhlIHR5cGUgb2YgZHJpdmUgdHJhaW5zIGF2YWlsYWJsZS4gCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpKwogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4PWNsYXNzLCB5PWRydikpCmBgYAoKIyMjIFNlY3Rpb24gMy4zOiBBZXN0aGV0aWMgbWFwcGluZ3MKClNjYXR0ZXJwbG90IHdpdGggY2FyIGNsYXNzIGNvZGVkCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpICsgCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgY29sb3IgPSBjbGFzcykpCmBgYAoKU2NhdHRlcnBsb3QgY29kZWQgYnkgY2FyIHNpemUgCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpICsgCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgc2l6ZSA9IGNsYXNzKSkKYGBgCgpTY2F0dGVycGxvdCB3aXRoIGFscGhhIGFlc3RoZXRpYwoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKSArIAogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3ksIGFscGhhID0gY2xhc3MpKQpgYGAKClNjYXR0ZXJwbG90IHdpdGggc2hhcGUgYWVzdGhldGljIApgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpICsgCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgc2hhcGUgPSBjbGFzcykpCmBgYAoKU2NhdHRlcnBsb3Qgd2l0aCBtYW51YWwgY29sb3IgYWRkZWQKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IG1wZykgKyAKICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSwgY29sb3IgPSAiYmx1ZSIpCmBgYAoKCiMjIyMgU2VjdGlvbiAzLjMgcXVlc3Rpb25zCgoqKjE6KiogV2hhdOKAmXMgZ29uZSB3cm9uZyB3aXRoIHRoaXMgY29kZT8gV2h5IGFyZSB0aGUgcG9pbnRzIG5vdCBibHVlPyBJbiBvcmRlciB0byBtYW51YWxseSBzZXQgYSBwbG90IGNvbG9yLCB0aGUgY29sb3IgaGFzIHRvIGJlIGxvY2F0ZWQgb3V0c2lkZSBvZiB0aGUgZ2VvbSBmdW5jdGlvbiBhZXMoKQoKCioqMjoqKiBXaGljaCB2YXJpYWJsZXMgaW4gYG1wZ2AgYXJlIGNhdGVnb3JpY2FsPyBWYXJpYWJsZXMgdGhhdCBhcmUgY2F0ZWdvcmljYWwgZG8gbm90IGNvbnRhaW4gYW4gaW50ZWdlciBvciBob2xkIGEgbnVtZXJpY2FsIHZhbHVlLiBTbywgbWFudWZhY3R1cmVyLCBtb2RlbCwgdHJhbnNtaXNzaW9uLCBkcml2ZSB0cmFpbiwgZnVlbCB0eXBlLCBhbmQgY2xhc3MgYXJlIGFsbCBjYXRlZ29yaWNhbCB2YXJpYWJsZXMuICBXaGljaCB2YXJpYWJsZXMgYXJlIGNvbnRpbnVvdXM/IFRoZSB2YXJpYWJsZXMgdGhhdCBob2xkIGEgbnVtZXJpY2FsIHZhbHVlIG9yIGlzIGFuIGludGVnZXIgd291bGQgYmUgYSBjb250aW51b3VzIHZhcmlhYmxlLiBTbywgZGlzcGxhY2VtZW50LCB5ZWFyLCBjeWxpbmRlciwgY2l0eSBtcGcsIGFuZCBod3kgbXBnIHdvdWxkIGJlIHRoZSBjb250aW51b3VzIHZhcmlhYmxlcy4gKCpIaW50OiogdHlwZSBgP21wZ2AgdG8gcmVhZCB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgdGhlIGRhdGFzZXQpLiBIb3cgY2FuIHlvdSBzZWUgdGhpcyBpbmZvcm1hdGlvbiB3aGVuIHlvdSBydW4gbXBnPyBXaGVuIHJ1bm5pbmcgP21wZyBpdCBkaWQgbm90IHJldHVybiBhbnkgaGVscCBvciByZXN1bHRzLiBBbiBvbmxpbmUgc2VhcmNoIHN1Z2dlc3RlZCBydW5uaW5nIGhlbHAobXBnKSBpbnN0ZWFkLiBUaGUgaGVscCByZXN1bHRzIGRpc3BsYXllZCB0aGUgdHlwZXMgb2YgdmFyaWFibGVzIGxpc3RlZCBmb3IgdGhlIGRhdGEgYW5kIGRlc2NyaWJlZCB0aGVpciBjb250ZW50LiAKCmBgYHtyfQo/bXBnCmBgYAoKYGBge3J9CmhlbHAobXBnKQpgYGAKCioqMzoqKiBNYXAgYSBjb250aW51b3VzIHZhcmlhYmxlIHRvIGNvbG9yLCBzaXplLCBhbmQgc2hhcGUuIEhvdyBkbyB0aGVzZSBhZXN0aGV0aWNzIGJlaGF2ZSBkaWZmZXJlbnRseSBmb3IgY2F0ZWdvcmljYWwgdnMuIGNvbnRpbnVvdXMgdmFyaWFibGVzPyBBZXN0aGV0aWNzIGJlaGF2ZSBiZXN0IGZvciBjYXRlZ29yaWNhbCB2YXJpYWJsZXMuICAqKk5vdGU6KiogWW91IG5lZWQgc2V2ZXJhbCBjb2RlIGNodW5rcyBoZXJlIHRvIGFuc3dlciB0aGlzIHF1ZXN0aW9uLgoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKSsKICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeD1kaXNwbCwgeT1od3ksIGNvbG9yPWN0eSkpCmBgYApgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpKwogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4PWRpc3BsLCB5PWh3eSwgc2l6ZT1jdHkpKQpgYGAKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IG1wZykrCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHg9ZGlzcGwsIHk9aHd5LCBhbHBoYT1jdHkpKQpgYGAKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKSsKICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeD1kaXNwbCwgeT1od3ksIHNoYXBlPWN0eSkpCmBgYAoKCioqNDoqKiBXaGF0IGhhcHBlbnMgaWYgeW91IG1hcCB0aGUgc2FtZSB2YXJpYWJsZSB0byBtdWx0aXBsZSBhZXN0aGV0aWNzPyBJbiB0aGlzIGNhc2UsIHZhcnlpbmcgY2xhc3NlcyB3ZXJlIGRpc3Rpbmd1aXNoZWQgYnkgYm90aCBkaWZmZXJlbnQgc2hhcGVzIGFuZCBjb2xvcnMuIAoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKSsKICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeD1kaXNwbCwgeT1od3ksIHNoYXBlPWNsYXNzLCBjb2xvcj1jbGFzcykpCmBgYAoKCioqNToqKiBXaGF0IGRvZXMgdGhlIHN0cm9rZSBhZXN0aGV0aWMgZG8/IFVzZSB0aGUgc3Ryb2tlIGFlc3RoZXRpYyB0byBtb2RpZnkgdGhlIHdpZHRoIG9mIHRoZSBib3JkZXIuIFdoYXQgc2hhcGVzIGRvZXMgaXQgd29yayB3aXRoPyBPbmx5IHNoYXBlcyB0aGF0IGhhdmUgYSBib3JkZXIuICAoKkhpbnQ6KiB1c2UgYD9nZW9tX3BvaW50YCkgCgpgYGB7cn0KP2dlb21fcG9pbnQKYGBgCgoKYGBge3J9CmdncGxvdChtdGNhcnMsIGFlcyh3dCwgbXBnKSkgKwogIGdlb21fcG9pbnQoc2hhcGUgPSAyMSwgY29sb3VyID0gImJsYWNrIiwgZmlsbCA9ICJ3aGl0ZSIsIHNpemUgPSA1LCBzdHJva2UgPSA1KQpgYGAKCgoqKjY6KiogV2hhdCBoYXBwZW5zIGlmIHlvdSBtYXAgYW4gYWVzdGhldGljIHRvIHNvbWV0aGluZyBvdGhlciB0aGFuIGEgdmFyaWFibGUgbmFtZSwgbGlrZSBgYWVzKGNvbG91ciA9IGRpc3BsIDwgNSlgPyBJdCBkaXNwbGF5cyBwb2ludHMgaW4gY29sb3IgYmFzZWQgb24gd2hldGhlciB0aGV5IG1lZXQgdGhlIG5hbWVkIHBhcmFtZXRlciBvciBub3QuIAoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKSsKICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeD1kaXNwbCwgeT1od3ksIGNvbG9yPSBkaXNwbCA8NSkpCmBgYAoKIyMjIFNlY3Rpb24gMy41OiBGYWNldHMKClNwbGl0IHBsb3QgaW50byBmYWNldHMKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IG1wZykgKyAKICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkgKyAKICBmYWNldF93cmFwKH4gY2xhc3MsIG5yb3cgPSAyKQpgYGAKClNwbGl0IHBsb3QgaW50byB2YXJpYWJsZXMKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IG1wZykgKyAKICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkgKyAKICBmYWNldF9ncmlkKGRydiB+IGN5bCkKYGBgCgoKCiMjIyMgU2VjdGlvbiAzLjUgcXVlc3Rpb25zCgoqKjE6KiogV2hhdCBoYXBwZW5zIGlmIHlvdSBmYWNldCBvbiBhIGNvbnRpbnVvdXMgdmFyaWFibGU/ICoqTm90ZToqKiBXcml0ZSBhIHByZWRpY3Rpb24sIHRoZW4gbWFrZSBhbmQgcnVuIHlvdXIgY29kZSBjaHVuay4gUHJlZGljdGlvbjogQWRkaW5nIGEgZmFjZXQgdG8gYSBjb250aW51b3VzIHZhcmlhYmxlIHdpbGwgbm90IHNwbGl0IHRoZSB2YXJpYWJsZSBpbnRvIGFsbCBzdWJwbG90cy4gCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpKwogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4PWRpc3BsLCB5PWh3eSkpKwogIGZhY2V0X3dyYXAofnllYXIpCmBgYAoKCioqMjoqKiBXaGF0IGRvIHRoZSBlbXB0eSBjZWxscyBpbiBwbG90IHdpdGggYGZhY2V0X2dyaWQoZHJ2IH4gY3lsKWAgbWVhbj8gSG93IGRvIHRoZXkgcmVsYXRlIHRvIHRoaXMgcGxvdD8gRm9yIHRoaXMgZGF0YSwgZW1wdHkgc3VicGxvdHMgcmVwcmVzZW50IHRoZSBkcml2ZSB0cmFpbiBhbmQgY3lsaW5kZXIgcGFpcmluZyB3YXMgZWl0aGVyIG5vdCB0ZXN0ZWQgb3Igbm90IGFuIGF2YWlsYmUgdmVoaWNsZSBvcHRpb24KCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IG1wZykrCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHg9ZGlzcGwsIHk9aHd5KSkrCiAgZmFjZXRfZ3JpZChkcnYgfiBjeWwpCmBgYAoKCioqMzoqKiBXaGF0IHBsb3RzIGRvZXMgdGhlIGZvbGxvd2luZyBjb2RlIG1ha2U/IFdoYXQgZG9lcyBgLmAgZG8/IEl0IGNob29zZXMgdGhlIGRpbWVuc2lvbiBvZiB0aGUgc3VicGxvdHMuIFRoZSAnLicgZGlzcGxheXMgdGhlIGRhdGEgaW4gcm93cyB3aGVyZWFzIHRoZSBvdGhlciBvbmUgaXMgZGlzcGxheWVkIGluIGNvbHVtbnMuLiAKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IG1wZykgKyAKICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkgKwogIGZhY2V0X2dyaWQoZHJ2IH4gLikKYGBgCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpICsgCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSkpICsKICBmYWNldF9ncmlkKC4gfiBjeWwpCmBgYAoKCioqNDoqKiBUYWtlIHRoZSBmaXJzdCBmYWNldGVkIHBsb3QgYmVsb3cuIFdoYXQgYXJlIHRoZSBhZHZhbnRhZ2VzIHRvIHVzaW5nIGZhY2V0aW5nIGluc3RlYWQgb2YgdGhlIGNvbG91ciBhZXN0aGV0aWM/IEl0IGFsbG93cyBmb3IgYWRkaXRpb25hbCB2YXJpYWJsZXMgdG8gYmUgdXNlZCB0byBzcGxpdCB0aGUgZGF0YS4gIFdoYXQgYXJlIHRoZSBkaXNhZHZhbnRhZ2VzPyBDYW4gb25seSBiZSB1c2VkIG9uIGNhdGVnb3JpY2FsIGRhdGEuIEhvdyBtaWdodCB0aGUgYmFsYW5jZSBjaGFuZ2UgaWYgeW91IGhhZCBhIGxhcmdlciBkYXRhc2V0PyBUb28gbWFueSBzdWJwbG90cyB0byBlYXNpbHkgY29tcGFyZSB0aGUgZGF0YS4KCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IG1wZykgKyAKICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkgKyAKICBmYWNldF93cmFwKH4gY2xhc3MsIG5yb3cgPSAyKQpgYGAKCgoKCioqNToqKiBSZWFkIGA/ZmFjZXRfd3JhcGAuIFdoYXQgZG9lcyBgbnJvd2AgZG8/ICducm93JyBjb250cm9scyB0aGUgbnVtYmVyIG9mICByb3dzLiBXaGF0IGRvZXMgYG5jb2xgIGRvPyAnbmNvbCcgY29udHJvbHMgdGhlIG51bWJlciBvZiBudW1iZXIgY29sdW1ucy4gV2hhdCBvdGhlciBvcHRpb25zIGNvbnRyb2wgdGhlIGxheW91dCBvZiB0aGUgaW5kaXZpZHVhbCBwYW5lbHM/IERpcmVjdGlvbiAnZGlyJyBiZWNhdXNlIHRoZXkgY291bGQgYmUgaW4gZWl0aGVyIGEgdmVydGljYWwgb3IgaG9yaXpvbnRhbCBsYXlvdXQuIFdoeSBkb2VzbuKAmXQgYGZhY2V0X2dyaWQoKWAgaGF2ZSBucm93IGFuZCBuY29sIGFyZ3VtZW50P2ogSW4gZmFjZXRfZ3JpZCB0aGUgbnVtYmVyIG9mIHZhcmlhYmxlIHByZWRldGVybWluZXMgdGhlIG51bWJlciBvZiByb3dzIGFuZCBjb2x1bW5zLiAKCmBgYHtyfQo/ZmFjZXRfd3JhcApgYGAKCioqNjoqKiBXaGVuIHVzaW5nIGBmYWNldF9ncmlkKClgIHlvdSBzaG91bGQgdXN1YWxseSBwdXQgdGhlIHZhcmlhYmxlIHdpdGggbW9yZSB1bmlxdWUgbGV2ZWxzIGluIHRoZSBjb2x1bW5zLiBXaHk/IFNvIHRoZSBheGlzIGlzIG1vcmUgc3ByZWFkIG91dCBhbGxvd2luZyBhbGwgdGhlIGRhdGEgdG8gYmUgc2Vlbi4gCgpgYGB7cn0KP2ZhY2V0X2dyaWQKYGBgCgoKIyMjIFNlY3Rpb24gMy42OiBHZW9tZXRyaWMgb2JqZWN0cwoKU2NhdHRlcnBsb3Qgb2YgbXBnIGRhdGEKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKSArIAogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3kpKQpgYGAKCkxpbmUgZ3JhcGggb2YgbXBnIGRhdGEKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKSArIAogIGdlb21fc21vb3RoKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSkKYGBgCgpMaW5lZ3JhcGggZGl2aWRlZCBpbiAzIGFlc3RoZXRpYyBsaW5lIHR5cGVzCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpICsgCiAgZ2VvbV9zbW9vdGgobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3ksIGxpbmV0eXBlID0gZHJ2KSkKYGBgCgpMaW5lIEdyYXBoCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpICsKICBnZW9tX3Ntb290aChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSkpCmBgYAoKTGluZSBncmFwaCB3aXRoIGxpbmUgdHlwZXMgc2hvd2luZyB2ZWhpY2xlIGRyaXZlIHRyYWluIHR5cGVzCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpICsKICBnZW9tX3Ntb290aChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgZ3JvdXAgPSBkcnYpKQpgYGAKTGluZSBncmFwaCB3aXRoIGRyaXZlIHRyYWluIHR5cGUgaW5kaWNhdGVkIHdpdGggbXVsdGlwbGUgY29sb3JlZCBsaW5lcwoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKSArCiAgZ2VvbV9zbW9vdGgoCiAgICBtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgY29sb3IgPSBkcnYpLAogICAgc2hvdy5sZWdlbmQgPSBGQUxTRQogICkKYGBgCgpTY2F0dGVycGxvdCBhbmQgbGluZSBncmFwaCBvZiBtcGcgZGF0YQoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKSArIAogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3kpKSArCiAgZ2VvbV9zbW9vdGgobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3kpKQpgYGAKCkxpbmUgZ3JhcGggYW5kIHNjYXR0ZXJwbG90IHdpdGggY29sb3IgYWVzdGhldGljCgoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnLCBtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSkpICsgCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKGNvbG9yID0gY2xhc3MpKSArIAogIGdlb21fc21vb3RoKCkKYGBgCgpMaW5lIGdyYXBoIGFuZCBzY2F0dGVycGxvdCB3aXRoIGNvbG9yIGFlc3RoZXRpYyB3aXRob3V0IHN0YW5kYXJkIGRldmlhdGlvbgoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnLCBtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSkpICsgCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKGNvbG9yID0gY2xhc3MpKSArIAogIGdlb21fc21vb3RoKGRhdGEgPSBmaWx0ZXIobXBnLCBjbGFzcyA9PSAic3ViY29tcGFjdCIpLCBzZSA9IEZBTFNFKQpgYGAKCgoKIyMjIyBTZWN0aW9uIDMuNi4xIFF1ZXN0aW9ucwoKKioxOioqIFdoYXQgZ2VvbSB3b3VsZCB5b3UgdXNlIHRvIGRyYXcgYSBsaW5lIGNoYXJ0PyAnZ2VvbV9saW5lJyBBIGJveHBsb3Q/ICdnZW9tX2JveHBsb3QnIEEgaGlzdG9ncmFtPyAnZ2VvbV9oaXN0b2dyYW0nIEFuIGFyZWEgY2hhcnQ/ICdnZW9tX2FyZWEnICAgICoqTm90ZToqKiBZb3Ugd2lsbCBoYXZlIHRvIG1ha2Ugc29tZSB0eXBlcyBvZiB0aGVzZSBjaGFydHMgaW4gUGFydCAyIG9mIHRoaXMgYXNzaWdubWVudC4KCmBgYHtyfQo/Z2VvbV9hcmVhCmBgYAoKKioyOioqIFJ1biB0aGlzIGNvZGUgaW4geW91ciBoZWFkIGFuZCBwcmVkaWN0IHdoYXQgdGhlIG91dHB1dCB3aWxsIGxvb2sgbGlrZS4gUHJlZGljdGlvbjogU2NhdHRlciBwbG90cyBhbmQgYSBzaW5nbGUgbGluZSBvZiBkYXRhLiAgVGhlbiwgcnVuIHRoZSBjb2RlIGluIFIgYW5kIGNoZWNrIHlvdXIgcHJlZGljdGlvbnMuIAoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnLCBtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgY29sb3IgPSBkcnYpKSArIAogIGdlb21fcG9pbnQoKSArIAogIGdlb21fc21vb3RoKHNlID0gRkFMU0UpCmBgYAoKCgoKKiozOioqIFdoYXQgZG9lcyBgc2hvdy5sZWdlbmQgPSBGQUxTRWAgZG8/IEl0IHJlbW92ZXMgdGhlIGxlZ2VuZC4gV2hhdCBoYXBwZW5zIGlmIHlvdSByZW1vdmUgaXQ/IFRoZW4gdGhlIGxlZ2VuZCBhcHBlYXJzLiAKKipOb3RlOioqIFNraXAgdGhlICJXaHkgZG8geW91IHRoaW5rIEkgdXNlZCBpdCBlYXJsaWVyIGluIHRoZSBjaGFwdGVyPyIgcXVlc3Rpb24uCgoKKio0OioqIFdoYXQgZG9lcyB0aGUgYHNlYCBhcmd1bWVudCB0byBgZ2VvbV9zbW9vdGgoKWAgZG8/IEl0IGFkZHMgdXBwZXIgYW5kIGxvd2VyIGVycm9yIGxpbWl0cyBvciBjb25maWRlbmNlIGJhbmRzLiAKCgoqKjU6KiogV2lsbCB0aGVzZSB0d28gZ3JhcGhzIGxvb2sgZGlmZmVyZW50PyBXaHkvd2h5IG5vdD8gTm8uIFRoZXkgZGlzcGxheSB0aGUgc2FtZSBkYXRhIHRoZSBjb2RlIGlzIGp1c3Qgd3JpdHRlbiBpbiB0d28gZGlmZmVyZW50IHdheXMuICAKCioqNjoqKiBSZWNyZWF0ZSB0aGUgUiBjb2RlIG5lY2Vzc2FyeSB0byBnZW5lcmF0ZSB0aGUgZm9sbG93aW5nIGdyYXBocy4gKipOb3RlOioqIEVudGVyIGEgc2VwYXJhdGUgY29kZSBjaHVuayBmb3IgZWFjaCBncmFwaCwgbnVtYmVyZWQgMSB0byA2LCBzdGFydGluZyByb3ctd2lzZSBhdCB1cHBlciBsZWZ0LiAKCjE6IHVwcGVyIGxlZnQuCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpICsgCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSksIHNpemU9NSkgKwogIGdlb21fc21vb3RoKG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5KSwgc2U9IEZBTFNFKQpgYGAKCgoyOiB1cHBlciByaWdodC4KCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IG1wZykgKyAKICBnZW9tX3BvaW50IChtYXBwaW5nID0gYWVzKHggPWRpc3BsLCB5ID0gaHd5KSwgc2l6ZT01KSsKICBnZW9tX3Ntb290aChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSwgZ3JvdXAgPSBkcnYpLCBzZT0gRkFMU0UpCmBgYAoKMzogbWlkZGxlIGxlZnQuCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcsIG1hcHBpbmcgPSBhZXMoeCA9IGRpc3BsLCB5ID0gaHd5LCBjb2xvciA9IGRydiwgc2l6ZT0gNCkpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9zbW9vdGgoc2UgPSBGQUxTRSkKYGBgCgoKNDogbWlkZGxlIHJpZ2h0LgoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKSArIAogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3ksIGNvbG9yPSBkcnYpLCBzaXplPTUpICsKICBnZW9tX3Ntb290aChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSksIHNlPSBGQUxTRSkKYGBgCgoKNTogbG93ZXIgbGVmdC4KCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IG1wZywgbWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3ksIGNvbG9yID0gZHJ2LCBzaXplPSAzKSkgKyAKICBnZW9tX3BvaW50KCkgKyAKICBnZW9tX3Ntb290aChhZXMobGluZXR5cGU9IGRydiksIHNlID0gRkFMU0UpCmBgYAoKCjY6IGxvd2VyIHJpZ2h0LiAqSGludDoqIFJlYWQgdGhlIGhlbHAgZmlsZSBmb3IgYGdlb21fcG9pbnRgLiBVc2UgYHNoYXBlID0gMjFgLCBgc3Ryb2tlID0gMmAsIGFuZCBgc2l6ZSA9IDNgLgoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKSArIAogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3ksIGNvbG9yPSBkcnYpLCBzaGFwZT0gMjEsIHNpemU9Mywgc3Ryb2tlPTIpCmBgYAoKCiMjIyBTZWN0aW9uIDMuNzogU3RhdGlzdGljYWwgdHJhbnNmb3JtYXRpb25zLgoKKipTa2lwIHRoaXMgc2VjdGlvbi4qKiBXZSBtYXkgcmV0dXJuIHRvIGl0IGxhdGVyLgoKCiMjIyBTZWN0aW9uIDMuOCBQb3NpdGlvbiBhZGp1c3RtZW50cwpCYXIgZ3JhcGgKYGBge3J9CmdncGxvdChkYXRhID0gZGlhbW9uZHMpICsgCiAgZ2VvbV9iYXIobWFwcGluZyA9IGFlcyh4ID0gY3V0LCBjb2xvdXIgPSBjdXQpKQpgYGAKQ29sb3JlZCBCYXIgR3JhcGgKYGBge3J9CmdncGxvdChkYXRhID0gZGlhbW9uZHMpICsgCiAgZ2VvbV9iYXIobWFwcGluZyA9IGFlcyh4ID0gY3V0LCBmaWxsID0gY3V0KSkKYGBgCgpCYXIgZ3JhcGggd2l0aCBwb3NpdGlvbiBhZGp1c3RtZW50CmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGRpYW1vbmRzKSArIAogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGN1dCwgZmlsbCA9IGNsYXJpdHkpKQpgYGAKCkJhciBncmFwaCB3aXRoIGxvdyBhbHBoYSBwb3NpdGlvbiBhZGp1c3RtZW50CmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGRpYW1vbmRzLCBtYXBwaW5nID0gYWVzKHggPSBjdXQsIGZpbGwgPSBjbGFyaXR5KSkgKyAKICBnZW9tX2JhcihhbHBoYSA9IDEvNSwgcG9zaXRpb24gPSAiaWRlbnRpdHkiKQpgYGAKCkJhciBncmFwaCB3aXRob3V0IGZpbGwKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGRpYW1vbmRzLCBtYXBwaW5nID0gYWVzKHggPSBjdXQsIGNvbG91ciA9IGNsYXJpdHkpKSArIAogIGdlb21fYmFyKGZpbGwgPSBOQSwgcG9zaXRpb24gPSAiaWRlbnRpdHkiKQpgYGAKCkJhciBncmFwaCB3aXRoIGZpbGwKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IGRpYW1vbmRzKSArIAogIGdlb21fYmFyKG1hcHBpbmcgPSBhZXMoeCA9IGN1dCwgZmlsbCA9IGNsYXJpdHkpLCBwb3NpdGlvbiA9ICJmaWxsIikKYGBgCgpCYXIgZ3JhcGggd2l0aCBkb2RnZSBwb3NpdGlvbgoKYGBge3J9CmdncGxvdChkYXRhID0gZGlhbW9uZHMpICsgCiAgZ2VvbV9iYXIobWFwcGluZyA9IGFlcyh4ID0gY3V0LCBmaWxsID0gY2xhcml0eSksIHBvc2l0aW9uID0gImRvZGdlIikKYGBgCgpTY2F0dGVycGxvdCB3aXRoIGppdHRlcgoKYGBge3J9CmdncGxvdChkYXRhID0gbXBnKSArIAogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gZGlzcGwsIHkgPSBod3kpLCBwb3NpdGlvbiA9ICJqaXR0ZXIiKQpgYGAKCgojIyMjIFNlY3Rpb24gMy44IFF1ZXN0aW9ucwoKKioxOioqIFdoYXQgaXMgdGhlIHByb2JsZW0gd2l0aCB0aGlzIHBsb3Q/IFNvbWUgcG9pbnRzIGFyZSBub3QgZGlzcGxheWVkIGR1ZSB0byBvdmVyIHBsb3R0aW5nLiBIb3cgY291bGQgeW91IGltcHJvdmUgaXQuIEl0IGNhbiBiZSBpbXByb3ZlZCBieSBzZXR0aW5nIHRoZSBwb3NpdGlvbiBhZGp1c3RtZW50IHRvIGppdHRlci4gICpIaW50OiogUmVtZW1iZXIgdGhlIHNpemUgb2YgdGhlIGBtcGdgIGRhdGEgc2V0IGZyb20gZWFybGllciBpbiB0aGlzIGV4ZXJjaXNlLiBEb2VzIHRoZSBudW1iZXIgb2YgcG9pbnRzIHNlZW0gY29ycmVjdD8gKipOb3RlOioqIFdyaXRlIHRoZSBjb2RlIHRvIGltcHJvdmUgaXQuCgpgYGB7cn0KZ2dwbG90KGRhdGEgPSBtcGcpICsgCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSBkaXNwbCwgeSA9IGh3eSksIHBvc2l0aW9uID0gImppdHRlciIpCmBgYAoKCgoqKjI6KiogV2hhdCBwYXJhbWV0ZXJzIHRvIGBnZW9tX2ppdHRlcigpYCBjb250cm9sIHRoZSBhbW91bnQgb2Ygaml0dGVyaW5nPyBXaWR0aCBhbmQgSGVpZ2h0CgoKKiozOioqIENvbXBhcmUgYW5kIGNvbnRyYWN0cyBgZ2VvbV9qaXR0ZXIoKWAgd2l0aCBgZ2VvbV9jb3VudCgpYC4gQm90aCBmZWF0dXJlcyBwcm92aWRlIHBvc2l0aW9uIGFkanVzdG1lbnQuIENvdW50IGRldGVybWluZXMgdGhlIG51bWJlciBvZiBvdmVybGFwcGluZyBwb2ludHMuIEppdHRlciBhZGRzIG5vaXNlIHRvIHRoZSBvdmVybGFwcyBzbyBtb3JlIG9mIGh0ZSBwbG90cyBhcmUgc2Vlbi4gCgoKKio0OioqIFdoYXQgaXMgdGhlIGRlZmF1bHQgcG9zaXRpb24gYWRqdXN0ZW1lbnQgZm9yIGBnZW9tX2JveHBsb3QoKWA/IFRoZSBkZWZhdWx0IHBvc2l0aW9uIGlzIGRvZGdlMi4gQ3JlYXRlIGEgdmlzdWFsaXphdGlvbiBvZiB0aGUgYG1wZ2AgZGF0YXNldCB0aGF0IGRlbW9uc3RyYXRlcyBpdC4KCmBgYHtyfQpnZ3Bsb3QobXBnLCBhZXMoZGlzcGwsIGh3eSkpICsKICBnZW9tX2JveHBsb3QoYWVzKGdyb3VwID0gY3R5KSkKYGBgCgoKIyMjIFNlY3Rpb24gMy45OiBDb29yZGluYXRlIHN5c3RlbXMKCioqTm90ZToqKiBSZWFkIGFib3V0IGFuZCBkbyBvbmx5IHRoZSBjb2RlIGNodW5rIGFzc29jaWF0ZWQgd2l0aCBgY29vcmRfZmxpcCgpYC4gYGNvb3JkX2ZsaXAoKWAgaXMgYSBncmVhdCBsYXllciB0byB1c2Ugd2hlbiB5b3UgaGF2ZSBjYXRlZ29yaWNhbCBkYXRhIHdpdGggbG9uZ2lzaCBuYW1lcyBhcyBpdCBtYWtlcyB0aGUgdGV4dCBlYXNpZXIgdG8gcmVhZC4KCkJveHBsb3QKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IG1wZywgbWFwcGluZyA9IGFlcyh4ID0gY2xhc3MsIHkgPSBod3kpKSArIAogIGdlb21fYm94cGxvdCgpCmBgYAoKQm94cGxvdCB3aXRoIGNvb3JkaW5hdGVzIGZsaXBwZWQKCmBgYHtyfQpnZ3Bsb3QoZGF0YSA9IG1wZywgbWFwcGluZyA9IGFlcyh4ID0gY2xhc3MsIHkgPSBod3kpKSArIAogIGdlb21fYm94cGxvdCgpICsKICBjb29yZF9mbGlwKCkKYGBgCgoKIyMjIFNlY3Rpb24gMy4xMDogVGhlIGxheWVyZWQgZ3JhbW1hciBvZiBncmFwaGljcwoKSnVzdCByZWFkIHRoaXMgc2VjdGlvbiBhcyBhIGNvbnRleHR1YWwgcmV2aWV3IG9mIGV2ZXJ5dGhpbmcgeW91IGp1c3QgbGVhcm5lZC4KCgo=